﻿package com.saumya.audio 
{
	
	import flash.events.EventDispatcher;
	
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundMixer;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;
	import flash.errors.IOError;
	
	import br.com.stimuli.loading.BulkLoader;
	
	
	/**
	 * @author Saumya
	 * @version 0.1
	 * @usage The base audio controller class
	 */
	
	public class AudioController extends EventDispatcher
	{
		private var _soundChannel:SoundChannel = null;
		private var _soundBgChannel:SoundChannel = null;
		private var smSound:Sound = null;
		
		private var _bulkLoader:BulkLoader = null;
		private var _loaderIdName:String = '';
		
		public static const ALL_AUDIO_LOAD_EVENT:String = 'allAudioLoadSuccessEvent';
		public static const AUDIO_COMPLETE_EVENT:String = 'onAudioCompleteEvent';
		
		public function AudioController(loaderId:String='main-module') 
		{
			trace(this, ' : AudioController : loaderId=',loaderId,'---------------------------------');
			this.loaderIdName = loaderId;
			this.init();
		}
		
		public function init():void
		{
			this.audioLoader = new BulkLoader(this.loaderIdName);
		}
		
		/**
		 * This should be overridden by individual modules to add their specific audios
		 * This checks for all the audios in this module to be loaded and once completed fires up the complete event
		 */
		public function addLoadables():void {
			trace(this,' : addLoadables : this.loaderIdName=',this.loaderIdName);
			this.audioLoader.addEventListener(BulkLoader.COMPLETE, onAllAudioLoad);
			//starts the loading
			this.audioLoader.start();
		}
		
		private function onAllAudioLoad(e:Event):void 
		{
			trace(this,' : AudioController : onAllAudioLoad : ');
			var audioLoadEvent:Event = new Event(AudioController.ALL_AUDIO_LOAD_EVENT, true, false);
			this.dispatchEvent(audioLoadEvent);
		}
		
		/**
		 * This has to be overridden by the individual controllers
		 * @param	audioId
		 */
		public function playAudio(audioId:String = ''):void {
		}
		
		/**
		 * Stops all the sounds
		 */
		public function stopSounds():void {
			SoundMixer.stopAll();
		}
		
		/**
		 * Stops the sound playing in the general audio channel
		 */
		public function stopGameSounds():void {
			this.soundChannel.stop();
		}
		
		/**
		 * Stops the Background sound of the game
		 */
		public function stopBgSound():void {
			this.soundBgChannel.stop();
		}
		
		private function playSound(soundURI:String):void {
			trace(this,' : playSound : ',soundURI);
			var req:URLRequest = new URLRequest(soundURI);
			this.smSound = new Sound();
			this.smSound.addEventListener(Event.COMPLETE, completeHandler);
            this.smSound.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
            this.smSound.load(req);
		}
		
		public function onAudioComplete(e:Event):void 
		{
			trace(this, ' : onAudioComplete : ', 'TODO: Play the synch audio if any');
			var eAudio:Event = new Event(AudioController.AUDIO_COMPLETE_EVENT, true);
			this.dispatchEvent(eAudio);
		}
		
		private function ioErrorHandler(e:IOErrorEvent):void 
		{
			trace(this, 'ERROR : ' + e);
		}
		
		private function completeHandler(e:Event):void 
		{
			this.soundChannel = this.smSound.play();
			this.soundChannel.addEventListener(Event.SOUND_COMPLETE, onAudioComplete);
		}
		
		public function destroyBulkLoader():void {
			BulkLoader.removeAllLoaders();
		}
		
		///////////////////////////GETTERs and SETTERS///////////////////
		
		/**
		 * TODO : comment
		 */
		public function get audioLoader():BulkLoader { return _bulkLoader; }
		
		public function set audioLoader(value:BulkLoader):void 
		{
			_bulkLoader = value;
		}
		
		
		/**
		 * TODO : comment
		 */
		public function get soundChannel():SoundChannel { return _soundChannel; }
		
		public function set soundChannel(value:SoundChannel):void 
		{
			_soundChannel = value;
		}
		
		public function get loaderIdName():String { return _loaderIdName; }
		
		public function set loaderIdName(value:String):void 
		{
			_loaderIdName = value;
		}
		
		public function get soundBgChannel():SoundChannel { return _soundBgChannel; }
		
		public function set soundBgChannel(value:SoundChannel):void 
		{
			_soundBgChannel = value;
		}
		
	}
	
}